package com.ljlib.core.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Environment;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 作者：HQY on 16/9/13 19:42
 * 邮箱：hqy_xz@126.com
 */
public class BitmapUtil {


    /** 图片的最大容量 阀值200KB */
    private static final int BITMAP_MAX_SIZE = 1024 * 1024;
    /** 图片的最大尺寸 */
    private static final int BITMAP_MAX_DISPLAY = 600;
    /** 图片圆角的度数 */
    private static final int BITMAP_ROUND_DEGREE = 20;

    /**
     * return a bitmap from service
     * @param url
     * @return bitmap type
     */
    public final static Bitmap returnBitMap(String url) {
        URL myFileUrl = null;
        Bitmap bitmap = null;
        try {
            myFileUrl = new URL(url);
            HttpURLConnection conn;

            conn = (HttpURLConnection) myFileUrl.openConnection();

            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bitmap;
    }
    /***
     * 图片的缩放方法
     *
     * @param bgimage
     *            ：源图片资源
     * @param newWidth
     *            ：缩放后宽度
     * @param newHeight
     *            ：缩放后高度
     * @return
     */
    public static Bitmap zoomImageToSize(Bitmap bgimage, double newWidth, double newHeight) {
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width, (int) height, matrix, true);
        return bitmap;
    }


    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 准备上传的图片路径，如果图片体积大于阀值，则压缩并返回压缩后的图片路径
     *
     * @param filePath
     *            原图片路径
     * @return 返回实际上传的图片路径（分为原图路径和压缩后的图片路径）
     */
    public String prepareFile(String filePath) {
        String fileLoadPath = null;
        try {
            if (getImageSize(filePath) > BITMAP_MAX_SIZE) {// 图片体积大于200K，先进行压缩
                // 压缩图片
                Bitmap bimap = compressImage(filePath);
                int orientation = getImageOrientation(Environment.getExternalStorageDirectory().getPath());
                Bitmap bitmaps = rotateBitmap(bimap, orientation);
                File fileSavePath = saveImageToTemp(bitmaps);
                if (fileSavePath != null)
                    fileLoadPath = fileSavePath.getAbsolutePath();
            } else {
                fileLoadPath = filePath;
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return fileLoadPath;
    }

    /**
     * 压缩图片。
     *
     * @param path
     *            图片路径
     * @return 压缩后的图片
     * @throws IOException
     */
    public Bitmap compressImage(String path) throws IOException {
        Bitmap bitmap = null;
        // 取得图片
        InputStream is = new FileInputStream(path);
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 这个参数代表，不为bitmap分配内存空间，只记录一些该图片的信息（例如图片大小），说白了就是为了内存优化
        options.inJustDecodeBounds = true;
        // 通过创建图片的方式，取得options的内容（这里就是利用了java的地址传递来赋值）
        BitmapFactory.decodeStream(is, null, options);
        // 关闭流
        is.close();

        // 计算 在最大宽高下需要压缩的倍率
        int bitmapDisplayScale = 0;
        while (true) {
            // 这一步是根据要设置的大小，使宽和高都能满足
            if ((options.outWidth >> bitmapDisplayScale <= BITMAP_MAX_DISPLAY)
                    && (options.outHeight >> bitmapDisplayScale <= BITMAP_MAX_DISPLAY)) {
                break;
            }
            bitmapDisplayScale += 1;
        }
        // 计算 在大小阀值下需要压缩的倍率
        int bitmapSizeScale = getBitmpaSizeScale(path);

        // 重新取得流，注意：这里一定要再次加载，不能二次使用之前的流！
        is = new FileInputStream(path);
        // 这个参数表示 新生成的图片为原始图片的几分之一。
        options.inSampleSize = (int) Math.pow(2.0D, bitmapDisplayScale >= bitmapSizeScale ? bitmapDisplayScale
                : bitmapSizeScale);
        // 这里之前设置为了true，所以要改为false，否则就创建不出图片
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        // 同时设置才会有效
        options.inPurgeable = true;
        // 当系统内存不够时候图片自动被回收
        options.inInputShareable = true;
        // 创建Bitmap
        bitmap = BitmapFactory.decodeStream(is, null, options);

        return bitmap;
    }
    private int getBitmpaSizeScale(String path) throws IOException {
        int scale = 0;
        int len = getImageSize(path);
        scale = len / BITMAP_MAX_SIZE;
        if (scale == 0) {
            scale = 1;
        }

        return scale;
    }

    private Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
        Matrix m = new Matrix();
        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            m.setRotate(90);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            m.setRotate(180);
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            m.setRotate(270);
        } else {
            return bitmap;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        try {
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true);
        } catch (OutOfMemoryError ooe) {
            m.postScale(1, 1);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true);
        }
        return bitmap;
    }
    /**
     *
     * @Title: rotateImage
     * @param path
     * @return void
     */
    private static int getImageOrientation(String path) {

        try {
            ExifInterface exifInterface = new ExifInterface(path);

            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            return orientation;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return ExifInterface.ORIENTATION_NORMAL;
    }
    /**
     * 保存压缩后的图片，并返回 文件
     *
     * @param bitmap
     * @return
     * @throws IOException
     * @throws FileNotFoundException
     */
    private File saveImageToTemp(Bitmap bitmap) throws IOException, FileNotFoundException {
        // SD卡可用
        if (FileUtils.isSDCardExist()) {
            File file = null;
            if (bitmap != null) {
                // 获取当前系统时间
                String fileName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                // 当前系统时间作为文件名
                String suffix = ".jpg";
                // 保存图片
                FileUtils.createFolderTemp();
                file = File.createTempFile("Temp_" + fileName, suffix, new File(FileUtils.getFolderTemp()));
                file.createNewFile();

                if (!file.isFile()) {
                    throw new FileNotFoundException();
                }

                FileOutputStream fOut = null;
                fOut = new FileOutputStream(file);
                // 将图片转为输出流
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
                // 关闭输出流
                fOut.flush();
                fOut.close();
            }
            return file;
        }
        return null;
    }
    /**
     * 获取图片大小(Byte)
     *
     * @param path
     * @return
     * @throws IOException
     */
    public static int getImageSize(String path) throws IOException {
        File file = new File(path);
        FileInputStream fls = new FileInputStream(file);
        float fileLen = fls.available();
        return (int) fileLen;
    }

}
